/* 
    <provides OS-like functionality using a scheduler which supports time-triggered tasks>
    Copyright (C) <2012>  <Jonathan D. Armstrong> <jonathan.armstrong AT mavs.uta.edu>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/**
 * @file   main.c
 * @Author Jonathan D. Armstrong (jonathan.armstrong@mavs.uta.edu)
 * @date   December, 2012
 * @brief  Brief description of file.
 *
 * Detailed description of file.
 */
 
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

/* configure platform-specific includes, noRTOS constants, etc.
   (FIXME: likely needs debugging if more than one platform is
    ever supported by noRTOS)
*/
#include "projectdefs.h"

/* provides access to basic OS-like functionality */
#include "nortos.h"

/* FIXME: should include in "projectdefs.h" to control port selection...or use makefile */
#include "hardware.h"
#include "state-machine.h"
#include "tasks.h"

/**
 * @name    Main
 * @brief   Initialize hardware and enter scheduler.
 * @ingroup example
 *
 * This API provides certain actions as an example.
 *
 * @param [in] repeat  Number of times to do nothing.
 *
 * @retval status   Return from main will do different things on embedded systems.
 *
 * Example Usage:
 * @code
 *    // not called directly by user code
 * @endcode
 */
/* main program entry */
int main(void)
{   
    /* error checking */
    bool ok;
    
    /* return status from functions */
    int status;
    
    /* initialize hardware using processor-specific function */
    printf("init_hardware()\r\n");
    init_hardware();
    
    /* useful to check for successful access to external RAM on some architectures */
    //xram_test();
    
    /* initialize task control block so all tasks start as invalid
       (this is done after init_hardware() because on some ports
        memory where the TCB lives may need to be initialized)
    */
    printf("init_tasks()\r\n");
    init_tasks();

    /* setup hardware (or simulated) timer and timer interrupt
       using processor-specific function
       (may only do this after init_tasks() is called so that
        seeminly valid task entries are not executed unintentionally)
    */
    printf("init_timer_interrupt()\r\n");
    init_timer_interrupt();
    
    /* should remain true if all create_task() calls are successful */
    ok = true;
    
    /* create tasks */
    status = create_task(&idle, 0, READY);
    ok &= (status >= 0);
    status = create_task(&blink_1hz, 1, DELAYED);
    ok &= (status >= 0);
    status = create_task(&lengthy_task, 1, DELAYED);
    ok &= (status >= 0);
    
    /* did a task fail to be created? */
    if (!ok)
    {
        printf("create_task() call failed (at least one)\r\n");
    }
    
    /* infinite loop */
    while(true)
    {
        /* this calls the scheduler to run tasks if enabled */
        nortos_run();
    }

    return 0;
}